package cmd;
import java.util.*;
import java.io.*;
import java.nio.channels.FileChannel;
//class - component of processing data
public class Model {
	static private File Directory;
	static private File WorkDirectory = new File("c:");
	static private File[] SubDirectory;
	
	//methods of class Model
	//constructor
	Model(String Path){Directory = new File (Path);}
	Model() {Directory = WorkDirectory;}
	//method of print the content directory
	public String[] dir(){
		printContentDirectory Object = new printContentDirectory();
		return Object.dirList(Directory);
	}
	//method of print the tree directory
	public String[] tree(){
		printTreeDirectory Object = new printTreeDirectory();
		@SuppressWarnings("rawtypes")
		Vector List = Object.listTree(Directory);
		String[] ListTree = new String[List.size()];
		List.copyInto(ListTree);
		return ListTree;
	}
	//methods of search the needed file with using mask
	public String[] find(String Mask){
		findFileInDirectory Object = new findFileInDirectory();
		@SuppressWarnings( "rawtypes" )
		Vector List = Object.findFiles(Directory, Mask);
		String ListInfo[] = new String[List.size()];
		List.copyInto(ListInfo);
		return ListInfo;
	}
	//method of copy the file in input directory
	public boolean copy(String srcPath,String dstPath){
		copyFile Object = new copyFile();
		return Object.copy(srcPath, dstPath);
	}
	//method of move the file in input directory
	public boolean move(String srcPath,String dstPath){
		boolean flag=false;
		copyFile copyObject = new copyFile();
		flag = copyObject.copy(srcPath, dstPath);
		deleteDir delObject = new deleteDir();
		flag = delObject.del(Directory);
		return flag;
	}
	//method of create the new directory
	public boolean mkdir(String mkPath){
		File mkDirectory = new File (mkPath);
		makeDirectory Object = new makeDirectory();
		return Object.mkDir(mkDirectory);
	}
	//method of change the work directory
	public File cd(String NewPath){
		changeWorkDirectory Object = new changeWorkDirectory();
		return Object.cd(NewPath);
	}
	//method of delete directory
	public boolean del(){
		deleteDir Object = new deleteDir();
		return Object.del(Directory);
	}
	
	class printContentDirectory {	
		private String[] List;
		
		private String[] dirList (File Directory){
			SubDirectory = Directory.listFiles();
			List = new String[SubDirectory.length];
			for (int i=0;i<SubDirectory.length;i++) 
				{
				List[i]="";
				List[i] += new Date(SubDirectory[i].lastModified());
				if (SubDirectory[i].isDirectory()) List[i]+="\t<DIR> \t";
				else List[i]+="\t<FILE>\t";
				List[i]+=SubDirectory[i].getName();
				}
			return List;
		}
	}
	
	class printTreeDirectory {
		@SuppressWarnings("rawtypes")
		private Vector List = new Vector();
		
		@SuppressWarnings("rawtypes")
		private Vector listTree(File Directory){
			contentTree(Directory,0);
			return List;
		}
		//recursive procedure for finding the contents of a directory
		@SuppressWarnings("unchecked")
		private void contentTree(File Directory,int Indents)
		{
			String indents="";
			for (int i=0;i<Indents;i++) indents+="-";
			List.add(indents);
			if (Directory.isFile()) List.add("<FILE> "+Directory.getName());
			else {
				File[] SubDirectory = Directory.listFiles();
				List.add("[+]<DIR> "+Directory.getName());
				for (File SubWay:SubDirectory)
					contentTree(SubWay,Indents+1);
			}
		}
	}
	
	class findFileInDirectory {
		@SuppressWarnings("rawtypes")
		private Vector List = new Vector();
		//recursive procedure to check the contents of a directory
		@SuppressWarnings("rawtypes")
		public Vector findFiles(File Directory,String Mask)
		{
			if (Directory.isFile()) getInfoFile(Directory,Mask);
			else {
				getInfoFile(Directory,Mask);
				File[] SubDirectory = Directory.listFiles();
				for (File SubWay:SubDirectory)
					findFiles(SubWay,Mask);
			}
			return List;
		}
		//display information about the file, if the mask is contained in its name
		@SuppressWarnings("unchecked")
		private void getInfoFile(File Object,String Mask){
				String Name = Object.getName();	
				if (Name.contains(Mask)) {
					List.add(Object.getPath()+"\n"+ Name + "\n" 
							+ new Date(Object.lastModified())+"\n");				
				}
		}
	}
	
	class copyFile {
		public boolean copy(String srcPath,String dstPath){
			try{
				/*FileChannel srcChannel = new FileInputStream(srcPath).getChannel();
				FileChannel dstChannel = new FileOutputStream(dstPath).getChannel();
				dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
				srcChannel.close();
				dstChannel.close();*/
				
				File srcFile = new File(srcPath);
				File dstFile = new File(dstPath);
				if (!dstFile.exists()) dstFile.mkdir();
				InputStream in = new FileInputStream(srcFile);
    	        OutputStream out = new FileOutputStream(dstFile); 
    	        byte[] buffer = new byte[1024];
    	        int length;
    	        //copy the file content in bytes 
    	        while ((length = in.read(buffer)) > 0){
    	    	   out.write(buffer, 0, length);
    	        }
    	        in.close();
    	        out.close();
				srcFile.renameTo(dstFile);
				return true;
			}
			catch (IOException e)
			{
				//e.printStackTrace();
				return false;
			}
		}
	}
	
	class makeDirectory {
		public boolean mkDir(File mkDirectory){
			return mkDirectory.mkdir();
		}
	}

	class deleteDir {
		public boolean del(File Directory) {
			return Directory.delete();
		}
	}

	class changeWorkDirectory {
		public File cd(String NewPath) {
			WorkDirectory = new File(NewPath);
			return WorkDirectory;
		}
	}
}


